package com.goldcn.file.util;

import com.sun.imageio.plugins.jpeg.JPEGImageWriter;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.*;


public class ImageUtil {

    /**
     * 图片旋转
     * @param imageSrc
     * @param orientation
     * @param bgcolor
     * @return
     * @throws IOException
     */
    public static void rotateImg(String imageSrc,String orientation,Color bgcolor) throws IOException {
        int degree=0;

        switch (Integer.parseInt(orientation)){
            case 6:
                degree=90;
                break;
            case 3:
                degree=180;
                break;
            case 8:
                degree=270;
                break;
            default:
                return ;
        }

        BufferedImage image=InputImage(imageSrc);

        int iw = image.getWidth();//原始图象的宽度
        int ih = image.getHeight();//原始图象的高度
        int w = 0;
        int h = 0;
        int x = 0;
        int y = 0;
        degree = degree % 360;
        if (degree < 0)
            degree = 360 + degree;//将角度转换到0-360度之间
        double ang = Math.toRadians(degree);//将角度转为弧度

        /**
         *确定旋转后的图象的高度和宽度
         */

        if (degree == 180 || degree == 0 || degree == 360) {
            w = iw;
            h = ih;
        } else if (degree == 90 || degree == 270) {
            w = ih;
            h = iw;
        } else {
            //int d = iw + ih;
            //w = (int) (d * Math.abs(Math.cos(ang)));
            //h = (int) (d * Math.abs(Math.sin(ang)));
            double cosVal = Math.abs(Math.cos(ang));
            double sinVal = Math.abs(Math.sin(ang));
            w = (int) (sinVal*ih) + (int) (cosVal*iw);
            h = (int) (sinVal*iw) + (int) (cosVal*ih);
        }

        x = (w / 2) - (iw / 2);//确定原点坐标
        y = (h / 2) - (ih / 2);

        BufferedImage rotatedImage = new BufferedImage(w, h, image.getType());

//        Graphics2D gs = (Graphics2D)rotatedImage.getGraphics();
        Graphics2D gs = rotatedImage.createGraphics();

        if(bgcolor==null){
            rotatedImage = gs.getDeviceConfiguration().createCompatibleImage(w, h, Transparency.OPAQUE);
        }else{
            //gs.setColor(bgcolor);
            //gs.fillRect(0, 0, w, h);//以给定颜色绘制旋转后图片的背景
        }

        AffineTransform at = new AffineTransform();
        at.rotate(ang, w / 2, h / 2);//旋转图象
        at.translate(x, y);
        AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC);
        op.filter(image, rotatedImage);
        image = rotatedImage;

//        ByteArrayOutputStream byteOut= new ByteArrayOutputStream();
//        ImageOutputStream iamgeOut = ImageIO.createImageOutputStream(byteOut);
//        ImageIO.write(image, "png", iamgeOut);
//        InputStream inputStream = new ByteArrayInputStream(byteOut.toByteArray());


        OutImage(imageSrc,image);
    }

    /**
     * 以JPEG编码保存图片
     *
     * @param image_to_save
     *            要处理的图像图片
     * @throws IOException
     */
    public static void saveAsJPEG(BufferedImage image_to_save,ByteArrayOutputStream byteOut) throws IOException {
        // Image writer
        JPEGImageWriter imageWriter = (JPEGImageWriter) ImageIO
                .getImageWritersBySuffix("jpg").next();

        ImageOutputStream ios = ImageIO.createImageOutputStream(byteOut);
        imageWriter.setOutput(ios);
        // and metadata
        IIOMetadata imageMetaData = imageWriter.getDefaultImageMetadata(
                new ImageTypeSpecifier(image_to_save), null);

        imageWriter.write(imageMetaData,
                new IIOImage(image_to_save, null, null), null);
        ios.close();
        imageWriter.dispose();

    }

    /**
     * 图片文件读取
     *
     * @param srcImgPath
     * @return
     */
    private static BufferedImage InputImage(String srcImgPath) {
        BufferedImage srcImage = null;
        FileInputStream in = null;
        try {
            in = new FileInputStream(srcImgPath);

            Image src = Toolkit.getDefaultToolkit().getImage(srcImgPath);
            srcImage = ImageUtil.toBufferedImage(src);

        } catch (IOException e) {
            System.out.println("读取图片文件出错！" + e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e) {

            }

        }
        return srcImage;
    }

    public static BufferedImage toBufferedImage(Image image) {
        if (image instanceof BufferedImage) {
            return (BufferedImage) image;
        }
        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();
        BufferedImage bimage = null;
        GraphicsEnvironment ge = GraphicsEnvironment
                .getLocalGraphicsEnvironment();
        try {
            int transparency = Transparency.OPAQUE;
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(image.getWidth(null),
                    image.getHeight(null), transparency);
        } catch (HeadlessException e) {
            // The system does not have a screen
        }
        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            bimage = new BufferedImage(image.getWidth(null),
                    image.getHeight(null), type);
        }
        // Copy image to buffered image
        Graphics g = bimage.createGraphics();
        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return bimage;
    }

    /**
     * 将图片按照指定的图片尺寸压缩
     *
     * @param srcImgPath 源图片路径
     * @param outImgPath 输出的压缩图片的路径
     * @param new_w      压缩后的图片宽
     * @param new_h      压缩后的图片高
     * @param isVerify   是否需要验证尺寸
     */
    public static boolean compressImage(String srcImgPath, String outImgPath,
                                        int new_w, int new_h,boolean isVerify){
        BufferedImage src = InputImage(srcImgPath);
        //判断新图尺寸是否小于原图尺寸
        if (null != src) {
            int old_w = src.getWidth();
            // 得到源图宽
            int old_h = src.getHeight();
            if(!isVerify||(isVerify&&verifyMeasure(src))){
                disposeImage(src, outImgPath, new_w, new_h);
                return true;
            }else{
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 指定长或者宽的最大值来压缩图片
     *
     * @param srcImgPath 源图片路径
     * @param outImgPath 输出的压缩图片的路径
     * @param maxLength  长或者宽的最大值
     */
    public static boolean compressImage(String srcImgPath, String outImgPath,
                                        int maxLength) {
        // 得到图片
        BufferedImage src = InputImage(srcImgPath);

        if (null != src) {
            int old_w = src.getWidth();
            // 得到源图宽
            int old_h = src.getHeight();
            // 得到源图长
            int new_w = 0;
            // 新图的宽
            int new_h = 0;
            //判断文件的尺寸是否符合要求
            if (old_h < 414 && old_w < 414) {
                return false;
            }
            // 新图的长
            // 根据图片尺寸压缩比得到新图的尺寸
            if (old_w > old_h) {
                // 图片要缩放的比例
                new_w = maxLength;
                new_h = (int) Math.round(old_h * ((float) maxLength / old_w));
            } else {
                new_w = (int) Math.round(old_w * ((float) maxLength / old_h));
                new_h = maxLength;
            }
            disposeImage(src, outImgPath, new_w, new_h);
            return true;
        } else {
            return false;
        }
    }

    public static void compressImage(BufferedImage srcImgPath, String outImgPath,
                                     int new_w, int new_h) {
        compressImage(srcImgPath, outImgPath, new_w, new_h);
    }


    /**
     * 处理图片
     *
     * @param src
     * @param outImgPath
     * @param new_w
     * @param new_h
     */
    private synchronized static void disposeImage(BufferedImage src,
                                                  String outImgPath, int new_w, int new_h) {
        // 得到图片
        int old_w = src.getWidth();
        // 得到源图宽
        int old_h = src.getHeight();
        // 得到源图长
        BufferedImage newImg = null;
        // 判断输入图片的类型
        switch (src.getType()) {
            case 13:
                // png,gif
//                newImg = new BufferedImage(new_w, new_h, BufferedImage.TYPE_4BYTE_ABGR);
//                newImg = new BufferedImage(BufferedImage.TYPE_BYTE_INDEXED);

                if (src.isAlphaPremultiplied()) {
                    newImg = new BufferedImage(new_w, new_h,BufferedImage.TRANSLUCENT);
                } else {
                    newImg = new BufferedImage(new_w, new_h, BufferedImage.TYPE_INT_RGB);
                }

                break;
            default:
                if (src.isAlphaPremultiplied()) {
                    newImg = new BufferedImage(new_w, new_h,BufferedImage.TRANSLUCENT);
                } else {
                    newImg = new BufferedImage(new_w, new_h, BufferedImage.TYPE_INT_RGB);
                }
//                newImg = new BufferedImage(new_w, new_h,src.getType());
                break;
        }



//        Graphics g = newImg.getGraphics();
        Graphics2D g = newImg.createGraphics();
        // 从原图上取颜色绘制新图
        g.drawImage(src, 0, 0, old_w, old_h,  Color.white,null);
        g.dispose();
        // 根据图片尺寸压缩比得到新图的尺寸
        newImg.getGraphics().drawImage(
                src.getScaledInstance(new_w, new_h, Image.SCALE_SMOOTH), 0, 0,
                null);
        // 调用方法输出图片文件
        OutImage(outImgPath, newImg);
    }

    /**
     * 将图片文件输出到指定的路径，并可设定压缩质量
     *
     * @param outImgPath
     * @param newImg
     */
    private static void OutImage(String outImgPath, BufferedImage newImg) {
        // 判断输出的文件夹路径是否存在，不存在则创建
        File file = new File(outImgPath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }// 输出到文件流
        try {
            ImageIO.write(newImg, outImgPath.substring(outImgPath
                    .lastIndexOf(".") + 1), new File(outImgPath));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //验证尺寸
    private static boolean verifyMeasure(BufferedImage src){
        int old_w = src.getWidth();
        // 得到源图宽
        int old_h = src.getHeight();
        if (old_h < 414 || old_w < 414) {
            return false;
        } else {
            return true;
        }
    }
}